﻿from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
import qrcode
from PIL import Image
import os
from decimal import Decimal
from io import BytesIO
from reportlab.lib.utils import ImageReader
#设置中文字体支持
pdfmetrics.registerFont(TTFont('CourierNew', 'ttfont\COUR.TTF'))
pdfmetrics.registerFont(TTFont('SIMSUN', 'ttfont\SIMSUN.TTC'))
pdfmetrics.registerFont(TTFont('SIMKAI', 'ttfont\SIMKAI.TTF'))

def crc16_x25(data):
    # The polynomial, initialized in reversed bit order.
    poly = 0xEDB88320
    # The initial value of the register.
    crc = 0x0000FFFF
 
    data = bytearray(data)
 
    for byte in data:
        for bit in range(8):
            if (crc & 0x8000):
                crc = ((crc << 1) ^ poly) & 0xFFFF
            else:
                crc = (crc << 1) & 0xFFFF
            crc = crc & 0xFFFF
            crc = crc | ((byte >> (7 - bit)) & 1)
 
    return crc

def getQRcode(strs):
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_M,
        box_size=10,
        border=0,
    )
    # 添加数据
    qr.add_data(strs)
    # 填充数据
    qr.make(fit=True)
    # 生成图片
    img = qr.make_image(fill_color="black", back_color="white")
    img = img.convert("CMYK")  # RGBA
    # 添加logo
    icon = Image.open("png/shui.png")
    # 获取图片的宽高
    img_w, img_h = img.size
    
    factor = 6
    size_w = int(img_w / factor)
    size_h = int(img_h / factor)
    #icon_w, icon_h = icon.size
    #按百分比计算固定logo图片大小
    icon_w = int(0.268*img_w)
    icon_h = int(0.268*img_h)
    if icon_w > size_w:
        icon_w = size_w
    if icon_h > size_h:
        icon_h = size_h
    # 重新设置logo的尺寸
    icon = icon.resize((icon_w, icon_h), 4)
    w = int((img_w - icon_w) / 2)
    h = int((img_h - icon_h) / 2)
 
 
    img.paste(icon, (w, h), None)
    # 显示图片
    # plt.imshow(img)
    # plt.show()
    img = img.convert('RGB')
    #img.save(fname)
    #return img
    #buf = BytesIO()
    #img.save(buf,'png')
    #image_stream = buf.getvalue()
    #buf.close()
    return img

def strx2y(c,s,pt,x,y):
    for i in range(0,len(s)):
        c.drawString(x, y-pt*i, s[i])
        
def gerdl(c,s,width):
    dls = ['']
    s_len = len(s)
    for i in range(0,s_len):        
        dls[len(dls)-1] +=s[i]
        if i<s_len-1:
            ss = dls[len(dls)-1]+s[i+1]
            if c.stringWidth(ss)>width:
                dls.append('')    
    return dls
    
def invoice_show(data, file,qianzhangpng='shanghai'):
    c = canvas.Canvas(file)
    c.setFont('SIMSUN', 9)
    qstrs = [
        '01',
        data['KPLX'],
        '',
        data["FPHM"],
        data["JSHJ"],
        data["KPRQ"].replace('年','').replace('月','').replace('日',''),
        '',   
    ]
    crc_str = hex(crc16_x25(','.join(qstrs).encode()))
    #print(crc_str)
    qstrs.append(crc_str[2:])
    qstr = ",".join(qstrs)
    print(qstr)
    #qimgname = f'qimg/{data["FPHM"]}.png'
    qimg = getQRcode(qstr)

    qimgname = ImageReader(qimg)
    #表格明细数据换行分割获得真实打印行数
    pz = ''
    match data['KPLX']:
        case '31':
            pz = '增值税专用发票'
        case '32':
            pz = '普通发票'
    listdata = data['datas']
    newlistdata = []
    for item in listdata:
        ItemNames = gerdl(c,item['ItemName'],37*mm-2)
        SpecMods = gerdl(c,item['SpecMod'],24*mm-2)
        if len(ItemNames) >= len(SpecMods):
            for i,itemName in enumerate(ItemNames):
                newlistdata.append({
                    'ItemName':itemName,
                    'SpecMod':SpecMods[i] if i<len(SpecMods) else '',
                    'MeaUnits':item['MeaUnits'] if i==0 else '',
                    'Quantity':item['Quantity'] if i==0 else '',
                    'UnPrice':item['UnPrice'] if i==0 else '',
                    'Amount':item['Amount'] if i==0 else '',
                    'TaxRate':item['TaxRate'] if i==0 else '',
                    'ComTaxAm':item['ComTaxAm'] if i==0 else ''
                })
        else:
            for i,specMod in enumerate(SpecMods):
                newlistdata.append({
                    'ItemName':ItemNames[i] if i<len(ItemNames) else '',
                    'SpecMod':specMod,
                    'MeaUnits':item['MeaUnits'] if i==0 else '',
                    'Quantity':item['Quantity'] if i==0 else '',
                    'UnPrice':item['UnPrice'] if i==0 else '',
                    'Amount':item['Amount'] if i==0 else '',
                    'TaxRate':item['TaxRate'] if i==0 else '',
                    'ComTaxAm':item['ComTaxAm'] if i==0 else ''
                })
    #print(len(newlistdata))
    
    #按照行数计算高度超过分割pdf页
    def split_array(arr, chunk_size):
        return [arr[i:i + chunk_size] for i in range(0, len(arr), chunk_size)]
    newlistdatas = split_array(newlistdata,47)
    page_count = len(newlistdatas)
    if len(newlistdatas[len(newlistdatas)-1])>42:
        page_count = page_count+1
    for index,_newlistdata in enumerate(newlistdatas):
        islast = False
        if index == len(newlistdatas) - 1:
            islast = True
        if len(_newlistdata) > 8 and len(_newlistdata) <= 12:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+17.5*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 12 and len(_newlistdata) <= 16:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*2,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*2)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 16 and len(_newlistdata) <= 20:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*3,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*3)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 20 and len(_newlistdata) <= 24:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*4,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*4)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 24 and len(_newlistdata) <= 28:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*5,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*5)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 28 and len(_newlistdata) <= 32:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*6,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*6)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 32 and len(_newlistdata) <= 36:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*7,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*7)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 36 and len(_newlistdata) <= 40:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*8,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*8)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 40 and len(_newlistdata) <= 42:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=17.5*8,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm+(17.5*8)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        elif len(_newlistdata) > 42 and len(_newlistdata) <= 47:
            #print('in 42-47')
            if islast:
                data['datas'] = _newlistdata[0:41]
                generate_invoice(c,pz,data,islast=False,yp=17.5*8,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
                c.drawImage(qimgname, 7*mm, 140*mm+(17.5*8)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
                c.showPage()
                data['datas'] = _newlistdata[42:]
                generate_invoice(c,pz,data,islast=False,yp=0,qianzhangpng='shanghai',pagecount=page_count,pageindex=index+1)
                c.drawImage(qimgname, 7*mm, 140*mm-27*mm,width=20*mm, height=20*mm,mask='auto',preserveAspectRatio=True)
            else:
                data['datas'] = _newlistdata
                generate_invoice(c,pz,data,islast=islast,yp=17.5*8+8.75*2,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
                c.drawImage(qimgname, 7*mm, 140*mm+(17.5*8+8.75*2)*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        else:
            data['datas'] = _newlistdata
            generate_invoice(c,pz,data,islast=islast,yp=0,qianzhangpng='shanghai',pagecount=page_count,pageindex=index)
            c.drawImage(qimgname, 7*mm, 140*mm-27*mm,width=20*mm,height=20*mm, mask='auto',preserveAspectRatio=True)
        if not islast:
            c.showPage()
    return c
    #generate_invoice(c,pz,data,islast=False,yp=0,qianzhangpng='shanghai')
    
    #c.showPage()
    #
    
def generate_invoice(c,pz,data,islast=True,yp=0,qianzhangpng='shanghai',pagecount=1,pageindex=0):
    yp = yp*mm
    pagesize = (210*mm, 140*mm+yp)
    c.setPageSize(pagesize)
    #c = canvas.Canvas(filename, pagesize=pagesize)
    
    #设置表格线颜色
    c.setStrokeColorRGB(0.5019607843137255,0,0)
    c.setFillColorRGB(0.5019607843137255,0,0)
    c.setLineWidth(0.25*mm)
    #表格外框线
    c.line(4.5*mm,16*mm,4.5*mm,110*mm+yp)
    c.line(4.5*mm,110*mm+yp,205.5*mm,110*mm+yp)
    c.line(205.5*mm,110*mm+yp,205.5*mm,16*mm)
    c.line(4.5*mm,16*mm,205.5*mm,16*mm)
    
    c.line(4.5*mm,88*mm+yp,205.5*mm,88*mm+yp)#购方信息销防信息横分割线
    if islast:
        c.line(4.5*mm,44*mm,205.5*mm,44*mm)#合计下横分割线
        c.line(4.5*mm,36*mm,205.5*mm,36*mm)#价税合计下分割线
    
    #竖分割线
    c.line(10.5*mm,88*mm+yp,10.5*mm,110*mm+yp)
    c.line(106*mm,88*mm+yp,106*mm,110*mm+yp)
    c.line(112*mm,88*mm+yp,112*mm,110*mm+yp)
    if islast:
        c.line(58.5*mm,44*mm,58.5*mm,36*mm)
        c.line(10.5*mm,36*mm,10.5*mm,16*mm)
    # 添加标题
    type_title = f'电子发票（{pz}）' 
    c.setFont('SIMKAI', 20)
    type_title_width = c.stringWidth(type_title)

    type_title_x = 210*mm/2-(type_title_width/2) #剧中坐标计算
    c.drawString(type_title_x, 140*mm+yp-8*mm-20, type_title)
    #标题下划线
    c.line(210*mm/2-73/2*mm,122*mm+yp,210*mm/2+73/2*mm,122*mm+yp)
    c.line(210*mm/2-73/2*mm,121*mm+yp,210*mm/2+73/2*mm,121*mm+yp)
    
    c.setFont('SIMKAI', 9)
    c.drawString(155*mm, 140*mm+yp-8*mm-20, "发票号码：")
    c.drawString(155*mm, 140*mm+yp-8*mm-20-9-3*mm, "开票日期：")
    
    c.drawString(11*mm, 140*mm+yp-36.5163*mm, "名称：")
    c.drawString(11*mm, 140*mm+yp-47.0163*mm, "统一社会信用代码/纳税人识别号：")
    
    c.drawString(112*mm, 140*mm+yp-36.5163*mm, "名称：")
    c.drawString(112*mm, 140*mm+yp-47.0163*mm, "统一社会信用代码/纳税人识别号：")
    
    strx2y(c,'购买方信息',9,6*mm,110*mm+yp-5*mm)
    strx2y(c,'销售方信息',9,107*mm,110*mm+yp-5*mm)
    if islast:
        strx2y(c,'备注',20,6*mm,34*mm-5*mm)
    
    #print(c.stringWidth("合      计"))
    c.drawString(16*mm, 88*mm+yp-9, "项目名称")
    c.drawString(41.5*mm, 88*mm+yp-9, "规格型号")
    c.drawString(66.5*mm, 88*mm+yp-9, "单  位")
    c.drawString(102.5*mm-22.5, 88*mm+yp-9, "数 量")
    c.drawString(127.5*mm-22.5, 88*mm+yp-9, "单 价")
    c.drawString(153.5*mm-22.5, 88*mm+yp-9, "金 额")
    c.drawString(153.5*mm+12, 88*mm+yp-9, "税率/征收率")
    c.drawString(204*mm-22.5, 88*mm+yp-9, "税 额")
    if islast:
        c.drawString(37*mm-45, 45*mm, "合      计")
        c.drawString(20*mm, 39*mm, "价税合计（大写）")
        c.drawString(144.5*mm, 39*mm, "（小写）")
    else:
        c.drawString(37*mm-45, 18*mm+12, "小      计")
        c.drawString(37*mm-45, 18*mm, "合      计")
        
    c.drawString(20*mm, 7.5*mm, "开票人：")
    #print(c.stringWidth("税率/征收率"))
    #票面数据添加
    c.setFillColorRGB(0,0,0)
    c.setFont('CourierNew', 12)
    c.drawString(11*mm+135, 140*mm+yp-47.0163*mm,data.get('GGFSBH'))
    c.drawString(112*mm+135, 140*mm+yp-47.0163*mm,data.get('XHFSBH'))
    c.setFont('SIMSUN', 9)
    c.drawString(155*mm+45, 140*mm+yp-8*mm-20, data.get('FPHM'))
    c.drawString(155*mm+45, 140*mm+yp-8*mm-29-3*mm, data.get('KPRQ'))
    c.drawString(11*mm+27, 140*mm+yp-36.5163*mm, data.get('GGFMC'))
    c.drawString(112*mm+27, 140*mm+yp-36.5163*mm, data.get('XHFMC'))
    
    #tableData = []
    #colWidths = [37*mm,24*mm,12*mm,25*mm,25*mm,26*mm,25*mm,27*mm]
    xiaoji = Decimal('0.00')
    xiaojise = Decimal('0.00')
    for i,item in enumerate(data['datas']):
        line_h = i*4.5*mm
        c.drawString(4.5*mm, 81*mm+yp-line_h, item['ItemName'])
        c.drawString(41.5*mm, 81*mm+yp-line_h, item['SpecMod'])
        dwlen = c.stringWidth(item['MeaUnits'])
        c.drawString(65.5*mm+(6*mm-dwlen/2), 81*mm+yp-line_h, item['MeaUnits'])
        sllen = c.stringWidth(item['Quantity'])
        c.drawString(102.5*mm-sllen, 81*mm+yp-line_h, item['Quantity'])
        djlen = c.stringWidth(item['UnPrice'])
        c.drawString(127.5*mm-djlen, 81*mm+yp-line_h, item['UnPrice'])
        jelen = c.stringWidth(item['Amount'])
        c.drawString(153.5*mm-jelen, 81*mm+yp-line_h, item['Amount'])
        sllen = c.stringWidth(item['TaxRate'])
        c.drawString(153.5*mm+(12.5*mm-sllen/2), 81*mm+yp-line_h, item['TaxRate'])
        selen = c.stringWidth(item['ComTaxAm'])
        c.drawString(204*mm-selen, 81*mm+yp-line_h, item['ComTaxAm'])
        if item['Amount']:
            xiaoji += Decimal(item['Amount']) 
        if item['ComTaxAm']:
            xiaojise += Decimal(item['ComTaxAm'])
    c.drawString(20*mm+36, 7.5*mm, data['KPR'])
    
    if islast:
        str_xiaoji = '%.2f' %xiaoji
        str_xiaoji_len = c.stringWidth(str_xiaoji)
        c.drawString(153.5*mm-str_xiaoji_len, 45*mm, str_xiaoji)
        str_xiaojise = '%.2f' %xiaojise
        str_xiaojise_len = c.stringWidth(str_xiaojise)
        c.drawString(204*mm-str_xiaojise_len, 45*mm, str_xiaojise)
        c.drawString(64*mm, 39*mm, cncurrency(data['JSHJ']))
        c.drawString(156*mm+6.6, 39*mm, data['JSHJ'])
        #备注换行计算
        bzs = data['BZ'].split('/r/n')#先按换行符分割
        bz_y = 33*mm
        bz_i = 0
        for bs in bzs:
            for p in gerdl(c,bs,194*mm):
                c.drawString(11*mm, bz_y-9*bz_i, p)
                bz_i += 1
    else:
        str_xiaoji = '%.2f' %xiaoji
        str_xiaoji_len = c.stringWidth(str_xiaoji)
        c.drawString(153.5*mm-str_xiaoji_len, 18*mm+12, str_xiaoji)
        str_xiaojise = '%.2f' %xiaojise
        str_xiaojise_len = c.stringWidth(str_xiaojise)
        c.drawString(204*mm-str_xiaojise_len, 18*mm+12, str_xiaojise)
        
        str_HJ = data['HJ']
        str_HJ_len = c.stringWidth(str_HJ)
        c.drawString(153.5*mm-str_HJ_len, 18*mm, str_HJ)
        str_HJSE = data['HJSE']
        str_HJSE_len = c.stringWidth(str_HJSE)
        c.drawString(204*mm-str_HJSE_len, 18*mm, str_HJSE)

    if pagecount>1:
        page_number_str = f"""共{pagecount}页 第{pageindex+1}页"""
        
        c.drawString(204.7103*mm-c.stringWidth(page_number_str), 111.7139*mm+yp, page_number_str)
    
    c.setFont('CourierNew', 11)
    if islast:
        c.drawString(153.5*mm-6.6-str_xiaoji_len, 45*mm, "¥")
        c.drawString(204*mm-6.6-str_xiaojise_len, 45*mm, "¥")
        c.drawString(156*mm, 39*mm, "¥")
        c.drawImage('png/x.png', 60*mm, 34*mm,width=4*mm, mask='auto',
              preserveAspectRatio=True)
    else:
        c.drawString(153.5*mm-6.6-str_xiaoji_len, 18*mm+12, "¥")
        c.drawString(204*mm-6.6-str_xiaojise_len, 18*mm+12, "¥")
        c.drawString(153.5*mm-6.6-str_HJ_len, 18*mm, "¥")
        c.drawString(204*mm-6.6-str_HJSE_len, 18*mm, "¥")
    
    #金色色带
    c.setStrokeColorRGB(0.9647058823529412,0.9294117647058824,0.8823529411764706)
    c.setLineWidth(0.54*mm)
    c.line(205.75*mm,110*mm+yp,205.75*mm,(110*mm+yp-16*mm)/2+16*mm)
    #咖啡色带
    c.setStrokeColorRGB(0.4627450980392157,0.34901960784313724,0.32941176470588235)
    c.line(205.75*mm,(110*mm+yp-16*mm)/2+16*mm,205.75*mm,16*mm)
    #盖章
    zhangpng = f'png/{qianzhangpng}.png'
    if os.path.exists(zhangpng):
        c.drawImage(zhangpng, 210*mm/2-15*mm, 140*mm+yp-60*mm,width=30*mm, mask='auto',
              preserveAspectRatio=True)
    # 保存PDF
    #c.save()


def cncurrency(value, capital=True, prefix=False, classical=None):
    '''
    参数:
    capital:    True   大写汉字金额
                False  一般汉字金额
    classical:  True   元
                False  圆
    prefix:     True   以'人民币'开头
                False, 无开头
    '''

    # 默认大写金额用圆，一般汉字金额用元
    if classical is None:
        classical = True if capital else False

    # 汉字金额前缀
    if prefix is True:
        prefix = '人民币'
    else:
        prefix = ''

    # 汉字金额字符定义
    dunit = ('角', '分')
    if capital:
        num = ('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖')
        iunit = [None, '拾', '佰', '仟', '万', '拾', '佰', '仟','亿', '拾', '佰', '仟', '万', '拾', '佰', '仟']
    else:
        num = ('〇', '一', '二', '三', '四', '五', '六', '七', '八', '九')
        iunit = [None, '十', '百', '千', '万', '十', '百', '千','亿', '十', '百', '千', '万', '十', '百', '千']
    if classical:
        iunit[0] = '元' if classical else '圆'
    # 转换为Decimal，并截断多余小数

    if not isinstance(value, Decimal):
        value = Decimal(value).quantize(Decimal('0.01'))

    # 处理负数
    if value < 0:
        prefix += '负'          # 输出前缀，加负
        value = - value         # 取正数部分，无须过多考虑正负数舍入
                                # assert - value + value == 0
    # 转化为字符串
    s = str(value)
    if len(s) > 19:
        raise ValueError('金额太大了，不知道该怎么表达。')
    istr, dstr = s.split('.')           # 小数部分和整数部分分别处理
    istr = istr[::-1]                   # 翻转整数部分字符串
    so = []     # 用于记录转换结果

    # 零
    if value == 0:
        return prefix + num[0] + iunit[0]
    haszero = False     # 用于标记零的使用
    if dstr == '00':
        haszero = True  # 如果无小数部分，则标记加过零，避免出现“圆零整”

    # 处理小数部分
    # 分
    if dstr[1] != '0':
        so.append(dunit[1])
        so.append(num[int(dstr[1])])
    else:
        so.append('整')         # 无分，则加“整”
    # 角
    if dstr[0] != '0':
        so.append(dunit[0])
        so.append(num[int(dstr[0])])
    elif dstr[1] != '0':
        so.append(num[0])       # 无角有分，添加“零”
        haszero = True          # 标记加过零了

    # 无整数部分
    if istr == '0':
        if haszero:             # 既然无整数部分，那么去掉角位置上的零
            so.pop()
        so.append(prefix)       # 加前缀
        so.reverse()            # 翻转
        return ''.join(so)

    # 处理整数部分
    for i, n in enumerate(istr):
        n = int(n)
        if i % 4 == 0:          # 在圆、万、亿等位上，即使是零，也必须有单位
            if i == 8 and so[-1] == iunit[4]:   # 亿和万之间全部为零的情况
                so.pop()                        # 去掉万
            so.append(iunit[i])
            if n == 0:                          # 处理这些位上为零的情况
                if not haszero:                 # 如果以前没有加过零
                    so.insert(-1, num[0])       # 则在单位后面加零
                    haszero = True              # 标记加过零了
            else:                               # 处理不为零的情况
                so.append(num[n])
                haszero = False                 # 重新开始标记加零的情况
        else:                                   # 在其他位置上
            if n != 0:                          # 不为零的情况
                so.append(iunit[i])
                so.append(num[n])
                haszero = False                 # 重新开始标记加零的情况
            else:                               # 处理为零的情况
                if not haszero:                 # 如果以前没有加过零
                    so.append(num[0])
                    haszero = True

    # 最终结果
    so.append(prefix)
    so.reverse()
    return ''.join(so)



if __name__ == '__main__': 
    # 发票数据样例
    invoice = {
        'KPLX':'31',
        'GGFMC':'购货方名称',
        'GGFSBH':'91320115MA27HYXA46',
        'XHFMC':'上海黄浦区大众养老院',
        'XHFSBH':'91310000767934044Y',
        'FPHM':'24312000000115629364',
        'KPRQ':'2024年04月25日',
        'JSHJ':'800000.00',
        'HJ':'1111111111.00',
        'HJSE':'222222222.00',
        'KPR':'彭清艳',
        'BZ':'''大苏打实打实的阿德飒飒大苏打撒旦啊实打实大苏打萨达'''
    }
    datas = [
        {
            'ItemName':'*人力资源服务*劳务劳务劳务劳务劳务劳务',
            'SpecMod':'规格型号1',
            'MeaUnits':'单位',
            'Quantity':'2',
            'UnPrice':'200000.00',
            'Amount':'400000.00',
            'TaxRate':'6%',
            'ComTaxAm':'24000.00'
        },
        {
            'ItemName':'*人力资源服务*劳务',
            'SpecMod':'规格型号2',
            'MeaUnits':'单位',
            'Quantity':'2',
            'UnPrice':'200000.00',
            'Amount':'400000.00',
            'TaxRate':'13%',
            'ComTaxAm':'24000.00'
        }        
    ]
    for i in range(1,91):
        datas.append({
            'ItemName':'*人力资源服务*劳务',
            'SpecMod':'规格型号2',
            'MeaUnits':'单',
            'Quantity':'2.00',
            'UnPrice':'200000.00',
            'Amount':'400000.00',
            'TaxRate':'6%',
            'ComTaxAm':'24000.00'
        })
    invoice['datas'] = datas
    # 生成PDF
    c = invoice_show(invoice, "invoice.pdf","shanghai")
    c.save()